home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / djgpp / libsrc / c / go32 / dpmi.c next >
Encoding:
C/C++ Source or Header  |  1993-10-16  |  9.1 KB  |  375 lines

  1. #include <dos.h>
  2. #include <go32.h>
  3. #include <sys/types.h>
  4. #include <dpmi.h>
  5.  
  6. static union REGS r;
  7. static struct SREGS s;
  8.  
  9. int _go32_dpmi_allocate_dos_memory(_go32_dpmi_seginfo *info)
  10. {
  11.   r.x.ax = 0x0100;
  12.   r.x.bx = info->size;
  13.   int86(0x31, &r, &r);
  14.   if (r.x.flags & 1)
  15.   {
  16.     info->size = r.x.bx;
  17.     return r.x.ax;
  18.   }
  19.   else
  20.   {
  21.     info->rm_segment = r.x.ax;
  22.     info->pm_selector = r.x.dx;
  23.     return 0;
  24.   }
  25. }
  26.  
  27. int _go32_dpmi_free_dos_memory(_go32_dpmi_seginfo *info)
  28. {
  29.   r.x.ax = 0x0101;
  30.   r.x.dx = info->pm_selector;
  31.   int86(0x31, &r, &r);
  32.   if (r.x.flags & 1)
  33.   {
  34.     return r.x.ax;
  35.   }
  36.   else
  37.   {
  38.     return 0;
  39.   }
  40. }
  41.  
  42. int _go32_dpmi_resize_dos_memory(_go32_dpmi_seginfo *info)
  43. {
  44.   r.x.ax = 0x0102;
  45.   r.x.bx = info->size;
  46.   r.x.dx = info->pm_selector;
  47.   int86(0x31, &r, &r);
  48.   if (r.x.flags & 1)
  49.   {
  50.     info->size = r.x.bx;
  51.     return r.x.ax;
  52.   }
  53.   else
  54.   {
  55.     return 0;
  56.   }
  57. }
  58.  
  59. int _go32_dpmi_get_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  60. {
  61.   r.x.ax = 0x0200;
  62.   r.h.bl = vector;
  63.   int86(0x31, &r, &r);
  64.   info->rm_segment = r.x.cx;
  65.   info->rm_offset = r.x.dx;
  66.   return 0;
  67. }
  68.  
  69. int _go32_dpmi_set_real_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  70. {
  71.   r.x.ax = 0x0201;
  72.   r.h.bl = vector;
  73.   r.x.cx = info->rm_segment;
  74.   r.x.dx = info->rm_offset;
  75.   int86(0x31, &r, &r);
  76.   return 0;
  77. }
  78.  
  79. int _go32_dpmi_get_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  80. {
  81.   r.x.ax = 0x0204;
  82.   r.h.bl = vector;
  83.   int86(0x31, &r, &r);
  84.   info->pm_selector = r.x.cx;
  85.   info->pm_offset = r.x.dx;
  86.   return 0;
  87. }
  88.  
  89. int _go32_dpmi_set_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  90. {
  91.   r.x.ax = 0x0205;
  92.   r.h.bl = vector;
  93.   r.x.cx = info->pm_selector;
  94.   r.x.dx = info->pm_offset;
  95.   int86(0x31, &r, &r);
  96.   if (r.x.flags & 1)
  97.   {
  98.     return r.x.ax;
  99.   }
  100.   else
  101.   {
  102.     return 0;
  103.   }
  104. }
  105.  
  106. static unsigned char wrapper_intcommon[] = {
  107. 0x1e,                        /* push    ds                  */
  108. 0x06,                        /* push    es                  */
  109. 0x0f, 0xa0,                    /* push    fs                  */
  110. 0x0f, 0xa8,                    /* push    gs                  */
  111. 0x60,                        /* pusha                       */
  112. 0x66, 0xb8, 0x34, 0x12,                /* mov     ax,0x1234           */
  113. 0x8e, 0xd8,                    /* mov     ds,ax               */
  114. 0x8e, 0xc0,                    /* mov     es,ax               */
  115. 0x8e, 0xe0,                    /* mov     fs,ax               */
  116. 0x8e, 0xe8,                    /* mov     gs,ax               */
  117. 0xe8, 0x00, 0x00, 0x00, 0x00,            /* call    _rmih               */
  118. 0x61,                        /* popa                        */
  119. 0x0f, 0xa9,                    /* pop     gs                  */
  120. 0x0f, 0xa1,                    /* pop     fs                  */
  121. 0x07,                        /* pop     es                  */
  122. 0x1f                        /* pop     ds                  */
  123. };
  124.  
  125. static unsigned char wrapper_intiret[] = {
  126. 0xcf                        /* iret                        */
  127. };
  128.  
  129. static unsigned char wrapper_intchain[] = {
  130. 0x2e, 0xff, 0x2d, 0x00, 0x00, 0x00, 0x00,    /* jmp     cs:[_old_int+39]    */
  131. 0xcf,                        /* iret                        */
  132. 0x78, 0x56, 0x34, 0x12,
  133. 0xcd, 0xab
  134. };
  135.  
  136. int _go32_dpmi_chain_protected_mode_interrupt_vector(int vector, _go32_dpmi_seginfo *info)
  137. {
  138.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_intcommon) + sizeof(wrapper_intchain));
  139.   if (wrapper == 0)
  140.     return 0x8015;
  141.  
  142.   r.x.ax = 0x0204;
  143.   r.h.bl = vector;
  144.   int86(0x31, &r, &r);
  145.  
  146.   memcpy(wrapper, wrapper_intcommon, sizeof(wrapper_intcommon));
  147.   memcpy(wrapper+sizeof(wrapper_intcommon), wrapper_intchain, sizeof(wrapper_intchain));
  148.   *(short *)(wrapper+9) = _go32_my_ds();
  149.   *(long *)(wrapper+20) = info->pm_offset - (int)wrapper - 24;
  150.   *(long *)(wrapper+sizeof(wrapper_intcommon)+3) = (long)wrapper+sizeof(wrapper_intcommon)+8;
  151.   *(long *)(wrapper+sizeof(wrapper_intcommon)+8) = r.x.dx;
  152.   *(short *)(wrapper+sizeof(wrapper_intcommon)+12) = r.x.cx;
  153.  
  154.   r.x.ax = 0x0205;
  155.   r.h.bl = vector;
  156.   r.x.cx = _go32_my_cs();
  157.   r.x.dx = (int)wrapper;
  158.   int86(0x31, &r, &r);
  159.   return 0;
  160. }
  161.  
  162. int _go32_dpmi_allocate_iret_wrapper(_go32_dpmi_seginfo *info)
  163. {
  164.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_intcommon) + sizeof(wrapper_intiret));
  165.   if (wrapper == 0)
  166.     return 0x8015;
  167.  
  168.   memcpy(wrapper, wrapper_intcommon, sizeof(wrapper_intcommon));
  169.   memcpy(wrapper+sizeof(wrapper_intcommon), wrapper_intiret, sizeof(wrapper_intiret));
  170.   *(long *)(wrapper+20) = info->pm_offset - (int)wrapper - 24;
  171.  
  172.   info->pm_offset = (int)wrapper;
  173.   return 0;
  174. }
  175.  
  176. int _go32_dpmi_free_iret_wrapper(_go32_dpmi_seginfo *info)
  177. {
  178.   free(info->pm_offset);
  179.   return 0;
  180. }
  181.  
  182. int _go32_dpmi_simulate_int(int vector, _go32_dpmi_registers *regs)
  183. {
  184.   r.h.bl = vector;
  185.   r.h.bh = 0;
  186.   r.x.cx = 0;
  187.   r.x.di = (int)regs;
  188.   if (vector == 0x21 && regs->x.ax == 0x4b00)
  189.   {
  190.     r.x.ax = 0xff0a;
  191.     int86(0x21, &r, &r);
  192.   }
  193.   else
  194.   {
  195.     r.x.ax = 0x0300;
  196.     int86(0x31, &r, &r);
  197.   }
  198.   if (r.x.flags & 1)
  199.   {
  200.     return r.x.ax;
  201.   }
  202.   else
  203.   {
  204.     return 0;
  205.   }
  206. }
  207.  
  208. int _go32_dpmi_simulate_fcall(_go32_dpmi_registers *regs)
  209. {
  210.   r.x.ax = 0x0301;
  211.   r.h.bh = 0;
  212.   r.x.cx = 0;
  213.   r.x.di = (int)regs;
  214.   int86(0x31, &r, &r);
  215.   if (r.x.flags & 1)
  216.   {
  217.     return r.x.ax;
  218.   }
  219.   else
  220.   {
  221.     return 0;
  222.   }
  223. }
  224.  
  225. int _go32_dpmi_simulate_fcall_iret(_go32_dpmi_registers *regs)
  226. {
  227.   r.x.ax = 0x0302;
  228.   r.h.bh = 0;
  229.   r.x.cx = 0;
  230.   r.x.di = (int)regs;
  231.   int86(0x31, &r, &r);
  232.   if (r.x.flags & 1)
  233.   {
  234.     return r.x.ax;
  235.   }
  236.   else
  237.   {
  238.     return 0;
  239.   }
  240. }
  241.  
  242. static unsigned char wrapper_common[] = {
  243. 0x66, 0x06,                /* push    es                  */
  244. 0x66, 0x1e,                /* push    ds                  */
  245. 0x66, 0x06,                /* push    es                  */
  246. 0x66, 0x1f,                /* pop     ds                  */
  247. 0x56,                    /* push    esi                 */
  248. 0x57,                    /* push    edi                 */
  249. 0xe8, 0x00, 0x00, 0x00, 0x00,        /* call    _rmcb               */
  250. 0x5f,                    /* pop     edi                 */
  251. 0x5e,                    /* pop     esi                 */
  252. 0x66, 0x1f,                /* pop     ds                  */
  253. 0x66, 0x07,                /* pop     es                  */
  254. 0xfc,                    /* cld                         */
  255. 0x66, 0x8b, 0x06,            /* mov     ax,[esi]            */
  256. 0x66, 0x26, 0x89, 0x47, 0x2a,        /* mov     es:[edi+42],ax      */
  257. 0x66, 0x8b, 0x46, 0x02,            /* mov     ax,[esi+2]          */
  258. 0x66, 0x26, 0x89, 0x47, 0x2c,        /* mov     es:[edi+44],ax      */
  259. };
  260.  
  261. static unsigned char wrapper_retf[] = {
  262. 0x66, 0x26, 0x83, 0x47, 0x2e, 0x04,    /* add     es:[edi+46],0x4     */
  263. 0xcf                    /* iret                        */
  264. };
  265.  
  266. static unsigned char wrapper_iret[] = {
  267. 0x66, 0x8b, 0x46, 0x04,            /* mov     ax,[esi+4]          */
  268. 0x66, 0x26, 0x89, 0x47, 0x20,        /* mov     es:[edi+32],ax      */
  269. 0x66, 0x26, 0x83, 0x47, 0x2e, 0x06,    /* add     es:[edi+46],0x6     */
  270. 0xcf                    /* iret                        */
  271. };
  272.  
  273. int _go32_dpmi_allocate_real_mode_callback_retf(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs)
  274. {
  275.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_common) + sizeof(wrapper_retf));
  276.   if (wrapper == 0)
  277.     return 0x8015;
  278.  
  279.   memcpy(wrapper, wrapper_common, sizeof(wrapper_common));
  280.   memcpy(wrapper+sizeof(wrapper_common), wrapper_retf, sizeof(wrapper_retf));
  281.   *(long *)(wrapper+11) = info->pm_offset - (int)wrapper - 15;
  282.   info->size = (int)wrapper;
  283.  
  284.   r.x.ax = 0x0303;
  285.   r.x.si = (int)wrapper;
  286.   r.x.di = (int)regs;
  287.   s.ds = _go32_my_cs();
  288.   s.es = _go32_my_ds();
  289.   s.fs = 0;
  290.   s.gs = 0;
  291.   int86x(0x31, &r, &r, &s);
  292.   if (r.x.flags & 1)
  293.   {
  294.     return r.x.ax;
  295.   }
  296.   else
  297.   {
  298.     info->rm_segment = r.x.cx;
  299.     info->rm_offset = r.x.dx;
  300.     return 0;
  301.   }
  302. }
  303.  
  304. int _go32_dpmi_allocate_real_mode_callback_iret(_go32_dpmi_seginfo *info, _go32_dpmi_registers *regs)
  305. {
  306.   unsigned char *wrapper = (unsigned char *)malloc(sizeof(wrapper_common) + sizeof(wrapper_iret));
  307.   if (wrapper == 0)
  308.     return 0x8015;
  309.  
  310.   memcpy(wrapper, wrapper_common, sizeof(wrapper_common));
  311.   memcpy(wrapper+sizeof(wrapper_common), wrapper_iret, sizeof(wrapper_iret));
  312.   *(long *)(wrapper+11) = info->pm_offset - (int)wrapper - 15;
  313.   info->size = (int)wrapper;
  314.  
  315.   r.x.ax = 0x0303;
  316.   r.x.si = (int)wrapper;
  317.   r.x.di = (int)regs;
  318.   s.ds = _go32_my_cs();
  319.   s.es = _go32_my_ds();
  320.   s.fs = 0;
  321.   s.gs = 0;
  322.   int86x(0x31, &r, &r, &s);
  323.   if (r.x.flags & 1)
  324.   {
  325.     return r.x.ax;
  326.   }
  327.   else
  328.   {
  329.     info->rm_segment = r.x.cx;
  330.     info->rm_offset = r.x.dx;
  331.     return 0;
  332.   }
  333. }
  334.  
  335. int _go32_dpmi_free_real_mode_callback(_go32_dpmi_seginfo *info)
  336. {
  337.   free(info->size);
  338.   r.x.ax = 0x0304;
  339.   r.x.cx = info->rm_segment;
  340.   r.x.dx = info->rm_offset;
  341.   int86(0x31, &r, &r);
  342.   if (r.x.flags & 1)
  343.   {
  344.     return r.x.ax;
  345.   }
  346.   else
  347.   {
  348.     return 0;
  349.   }
  350. }
  351.  
  352. int _go32_dpmi_get_free_memory_information(_go32_dpmi_meminfo *info)
  353. {
  354.   r.x.ax = 0x0500;
  355.   r.x.di = (int)info;
  356.   int86(0x31, &r, &r);
  357.   return 0;
  358. }
  359.  
  360. u_long _go32_dpmi_remaining_physical_memory()
  361. {
  362.   _go32_dpmi_meminfo info;
  363.   _go32_dpmi_get_free_memory_information(&info);
  364.   if (info.available_physical_pages)
  365.     return info.available_physical_pages * 4096;
  366.   return info.available_memory;
  367. }
  368.  
  369. u_long _go32_dpmi_remaining_virtual_memory()
  370. {
  371.   _go32_dpmi_meminfo info;
  372.   _go32_dpmi_get_free_memory_information(&info);
  373.   return info.available_memory;
  374. }
  375.